package com.rockcent.mall.lib.repository;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.rockcent.common.common.PageResult;
import com.rockcent.common.common.SQLPageDoing;
import com.rockcent.common.utils.RDateUtils;
import com.rockcent.mall.lib.domain.MerchantRechargeFlow;
import com.rockcent.mall.lib.domain.enumclass.AuditStatus;
import com.rockcent.mall.lib.domain.enumclass.MerchantPayType;
import com.rockcent.mall.lib.domain.enumclass.MerchantRechargeStatus;
import com.rockcent.mall.lib.dto.MerchantRechargeFlowDto;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import java.text.ParseException;
import java.util.Arrays;
import java.util.Map;

/**
 * Created by DK on 17/3/28.
 */
@Repository
public class MerchantRechargeFlowRepositoryImpl implements MerchantRechargeFlowRepositoryCustom {

    private static final Logger log = LoggerFactory.getLogger(MerchantRechargeFlowRepositoryImpl.class);

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public PageResult<MerchantRechargeFlowDto> findMerchantRechargePage(MerchantRechargeFlowDto dto, Long mallId, PageResult page) {
        SQLPageDoing<MerchantRechargeFlowDto> doing = (sql, fields, params, typeReferenceMap) -> {
            sql.append("select %s from merchant_recharge_flow mf left join merchant m on mf.merchant_id = m.id where 1=1 and mf.mall_id =:mallId");

            if (null != mallId) {
                params.put("mallId", mallId);
            }
            if (StringUtils.isNotBlank(dto.getMerchantName())) {
                sql.append(" and m.name like :merchantName");
                params.put("merchantName", "%" + dto.getMerchantName() + "%");
            }
            if (dto.getMerchantId() != null) {
                sql.append(" and mf.merchant_id = :merchantId");
                params.put("merchantId", dto.getMerchantId());
            }
            if (dto.getRechargeAmount() != null) {
                sql.append(" and mf.recharge_amount = :rechargeAmount");
                params.put("rechargeAmount", dto.getRechargeAmount());
            }
            if (dto.getRechargeAccount() != null) {
                sql.append(" and mf.recharge_account = :rechargeAccount");
                params.put("rechargeAccount", dto.getRechargeAccount());
            }
            if (StringUtils.isNotBlank(dto.getPayType())) {
                sql.append(" and mf.pay_type = :payType");
                params.put("payType", dto.getPayType());
            }

            if (MerchantRechargeStatus.WAIT != MerchantRechargeStatus.valueOf(dto.getRechargeStatus())) {
                //审核时间
                if (StringUtils.isNotBlank(dto.getBeginDate()) && StringUtils.isNotBlank(dto.getEndDate())) {
                    sql.append(" AND mf.date_audited >=:commitStartDate AND mf.date_audited <:commitEndDate");
                    params.put("commitStartDate", RDateUtils.beforeDateStr(dto.getBeginDate(), 0));
                    params.put("commitEndDate", RDateUtils.afterDateStr(dto.getEndDate(), 1));

                } else if (StringUtils.isNotBlank(dto.getBeginDate())) {
                    sql.append(" AND mf.date_audited >=:commitStartDate");
                    params.put("commitStartDate", RDateUtils.beforeDateStr(dto.getBeginDate(), 0));
                } else if (StringUtils.isNotBlank(dto.getEndDate())) {
                    sql.append(" AND mf.date_audited <:commitEndDate");
                    params.put("commitEndDate", RDateUtils.afterDateStr(dto.getEndDate(), 1));
                }
            }
            if (MerchantRechargeStatus.WAIT == MerchantRechargeStatus.valueOf(dto.getRechargeStatus())) {
                //汇款时间
                if (StringUtils.isNotBlank(dto.getRechargeBeginDate()) && StringUtils.isNotBlank(dto.getRechargeEndDate())) {
                    sql.append(" AND mf.recharge_date >=:startDate AND mf.recharge_date <:endDate");
                    params.put("startDate", RDateUtils.beforeDateStr(dto.getRechargeBeginDate(), 0));
                    params.put("endDate", RDateUtils.afterDateStr(dto.getRechargeEndDate(), 1));

                } else if (StringUtils.isNotBlank(dto.getRechargeBeginDate())) {
                    sql.append(" AND mf.recharge_date >=:startDate");
                    params.put("startDate", RDateUtils.beforeDateStr(dto.getRechargeBeginDate(), 0));
                } else if (StringUtils.isNotBlank(dto.getRechargeEndDate())) {
                    sql.append(" AND mf.recharge_date <:endDate");
                    params.put("endDate", RDateUtils.afterDateStr(dto.getRechargeEndDate(), 1));
                }
                //提交时间
                if (StringUtils.isNotBlank(dto.getBeginDate()) && StringUtils.isNotBlank(dto.getEndDate())) {
                    sql.append(" AND mf.date_created >=:commitStartDate AND mf.date_created <:commitEndDate");
                    params.put("commitStartDate", RDateUtils.beforeDateStr(dto.getBeginDate(), 0));
                    params.put("commitEndDate", RDateUtils.afterDateStr(dto.getEndDate(), 1));
                } else if (StringUtils.isNotBlank(dto.getEndDate())) {
                    sql.append(" AND mf.date_created <:commitEndDate");
                    params.put("commitEndDate", RDateUtils.afterDateStr(dto.getEndDate(), 1));
                } else if (StringUtils.isNotBlank(dto.getBeginDate())) {
                    sql.append(" AND mf.date_created >=:commitStartDate");
                    params.put("commitStartDate", RDateUtils.beforeDateStr(dto.getBeginDate(), 0));
                }
                sql.append(" and mf.recharge_status = :auditStatus");
                params.put("auditStatus", dto.getRechargeStatus());
                sql.append(" order by mf.date_created desc");
            } else if (MerchantRechargeStatus.AUDITED == MerchantRechargeStatus.valueOf(dto.getRechargeStatus())) {
                sql.append(" AND mf.recharge_status in (:auditStatus) ");
                params.put("auditStatus", Arrays.asList(MerchantRechargeStatus.SUCCESS.toString(), MerchantRechargeStatus.FAIL.toString()));
                sql.append(" order by mf.date_audited desc");
            } else {
                sql.append(" and mf.recharge_status = :auditStatus");
                params.put("auditStatus", dto.getRechargeStatus());
                sql.append(" order by mf.date_audited desc");
            }
            fields.append("mf.*, m.name merchantName");
        };
        return doing.go(page, MerchantRechargeFlowDto.class, objectMapper, jdbcTemplate, log);
    }

    /**
     * 商户查询充值记录
     *
     * @param dto
     * @param page
     * @return
     */
    @Override
    public PageResult<MerchantRechargeFlowDto> findAllMerchantRechargePage(MerchantRechargeFlowDto dto, PageResult page) {
        SQLPageDoing<MerchantRechargeFlowDto> doing = (sql, fields, params, typeReferenceMap) -> {
            sql.append("select %s from merchant_recharge_flow mf  where 1=1 and pay_type <> 'BASE_SERVICE_PAYMENTS' and pay_type <> 'RECHARGE_MALL'");

            if (dto.getMerchantId() != null) {
                sql.append(" and mf.merchant_id = :merchantId");
                params.put("merchantId", dto.getMerchantId());
            }
            if (StringUtils.isNotBlank(dto.getPayType())) {
                if (MerchantPayType.ALL.toString().equals(dto.getPayType())) {
                    sql.append(" and mf.pay_type in ('ONLINE','OUTLINE')");
                } else {
                    sql.append(" and mf.pay_type = :payType");
                    params.put("payType", dto.getPayType());
                }
            }

            //提交时间
            buildCommitDate(dto, sql, params);

            if (MerchantRechargeStatus.ALL != MerchantRechargeStatus.valueOf(dto.getRechargeStatus())) {
                sql.append(" AND mf.recharge_status =:auditStatus");
                params.put("auditStatus", dto.getRechargeStatus());
            }
            sql.append(" order by mf.date_created desc");
            fields.append("mf.*");
        };
        return doing.go(page, MerchantRechargeFlowDto.class, objectMapper, jdbcTemplate, log);
    }

    private void buildCommitDate(MerchantRechargeFlowDto dto, StringBuilder sql, Map<String, Object> params) throws ParseException {
        if (StringUtils.isNotBlank(dto.getBeginDate()) && StringUtils.isNotBlank(dto.getEndDate())) {
            sql.append(" AND mf.date_created >=:commitStartDate AND mf.date_created <:commitEndDate");
            params.put("commitStartDate", RDateUtils.beforeDateStr(dto.getBeginDate(), 0));
            params.put("commitEndDate", RDateUtils.afterDateStr(dto.getEndDate(), 1));

        } else if (StringUtils.isNotBlank(dto.getBeginDate())) {
            sql.append(" AND mf.date_created >=:commitStartDate");
            params.put("commitStartDate", RDateUtils.beforeDateStr(dto.getBeginDate(), 0));
        } else if (StringUtils.isNotBlank(dto.getEndDate())) {
            sql.append(" AND mf.date_created <:commitEndDate");
            params.put("commitEndDate", RDateUtils.afterDateStr(dto.getEndDate(), 1));
        }
    }
}
